<html><head><meta charset="utf-8"/><title>koa</title></head><body><h1>koa</h1><div class="x-wiki-content x-main-content">
 <p>
  koa是Express的下一代基于Node.js的web框架，目前有1.x和2.0两个版本。
 </p>
 <h3>
  历史
 </h3>
 <h4>
  1. Express
 </h4>
 <p>
  Express是第一代最流行的web框架，它对Node.js的http进行了封装，用起来如下：
 </p>
 <pre><code>var express = require('express');
var app = express();

app.get('/', function (req, res) {
    res.send('Hello World!');
});

app.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});
</code></pre>
 <p>
  虽然Express的API很简单，但是它是基于ES5的语法，要实现异步代码，只有一个方法：回调。如果异步嵌套层次过多，代码写起来就非常难看：
 </p>
 <pre><code>app.get('/test', function (req, res) {
    fs.readFile('/file1', function (err, data) {
        if (err) {
            res.status(500).send('read file1 error');
        }
        fs.readFile('/file2', function (err, data) {
            if (err) {
                res.status(500).send('read file2 error');
            }
            res.type('text/plain');
            res.send(data);
        });
    });
});
</code></pre>
 <p>
  虽然可以用async这样的库来组织异步代码，但是用回调写异步实在是太痛苦了！
 </p>
 <h4>
  2. koa 1.0
 </h4>
 <p>
  随着新版Node.js开始支持ES6，Express的团队又基于ES6的generator重新编写了下一代web框架koa。和Express相比，koa 1.0使用generator实现异步，代码看起来像同步的：
 </p>
 <pre><code>var koa = require('koa');
var app = koa();

app.use('/test', function *() {
    yield doReadFile1();
    var data = yield doReadFile2();
    this.body = data;
});

app.listen(3000);
</code></pre>
 <p>
  用generator实现异步比回调简单了不少，但是generator的本意并不是异步。Promise才是为异步设计的，但是Promise的写法……想想就复杂。为了简化异步代码，ES7（目前是草案，还没有发布）引入了新的关键字
  <code>
   async
  </code>
  和
  <code>
   await
  </code>
  ，可以轻松地把一个function变为异步模式：
 </p>
 <pre><code>async function () {
    var data = await fs.read('/file1');
}
</code></pre>
 <p>
  这是JavaScript未来标准的异步代码，非常简洁，并且易于使用。
 </p>
 <h4>
  3. koa2
 </h4>
 <p>
  koa团队并没有止步于koa 1.0，他们非常超前地基于ES7开发了koa2，和koa 1相比，koa2完全使用Promise并配合
  <code>
   async
  </code>
  来实现异步。
 </p>
 <p>
  koa2的代码看上去像这样：
 </p>
 <pre><code>app.use(async (ctx, next) =&gt; {
    await next();
    var data = await doReadFile();
    ctx.response.type = 'text/plain';
    ctx.response.body = data;
});
</code></pre>
 <p>
  出于兼容性考虑，目前koa2仍支持generator的写法，但下一个版本将会去掉。
 </p>
 <h3>
  选择哪个版本？
 </h3>
 <p>
  目前JavaScript处于高速进化中，ES7是大势所趋。为了紧跟时代潮流，教程将使用最新的koa2开发！
 </p>
</div>
</body></html>